﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//day 13
//一、选择题
//x 1 -- > C 23  补码补码！！ x = x | (x + 1)的作用是对整形中0的个数进行统计，没执行一次，减少一个0
//int main()
//{
//	unsigned int n = 0;
//	return 0;
//}
//1、如果 x = 2014 ，下面函数的返回值是（ ）
//int fun(unsigned int x)
//{
//	int n = 0;
//	while (x + 1)
//	{
//		n++;0000000000000000000000000000000
//		x = x | (x + 1);
//	}
//	return n;
//}
////int main()
////{
////	fun(2014);
////	unsigned int a = 0xffffffff; // 11111111 11111111 11111111 11111111 再+1 就变成0了
////	int b = 0x80000001;			// 10000000
////	printf("%u\n", a); 
////	printf("%d\n", b);
////
////	return 0;
////}
//A : 20 B : 21 C : 23 D 25



//x 2  --> B
//2、下列语句定义 x 为指向 int 类型变量 a 的指针，其中哪一个是正确的（ ）
//A : int a, *x = a; B: int a, * x = &a; C: int* x = &a, a; D: int a, x = a;



//x 3 --> D   返回NULL 
// 0地址是非法地址。
//目前计算机系统使用的是虚拟地址。
//每个地址都是经过映射的。
//0地址是被规定为空地址， 也就是非法地址，禁止读取或赋值
// 
//3、下面有关空指针和未初始化指针，说法错误的是（ ）
//A : 对0x0这个地址取值是非法的
//B : 空指针可以确保不指向任何对象或函数; 而未初始化指针则可能指向任何地方
//C : 空指针与任何对象或函数的指针值都不相等
//D : malloc在其内存分配失败时返回的是一个未初始化的指针



//x 4 -->  C   先计算++ C选项a[0]先和++结合，形成一个表达式，不能对表达式取地址，会报错
//4、若有定义 int a[8]; ，则以下表达式中不能代表数组元素 a[1] 的地址的是（ ）
//A : &a[0] + 1  B : &a[1]  C : &a[0]++  D : a + 1



//x 5 --> A 指针相加无意义而且可能越界，不允许  C赋值可以 int* p = &a;   p= &b;
//5、以下选项中，对基本类型相同的两个指针变量不能进行运算的运算符是（ ）
//A:+  B:-  C:=  D:==



//二、编程题
//有一种兔子，从出生后第3个月起每个月都生一只兔子，小兔子长到第三个月后每个月又生一只兔子。
//例子：假设一只兔子第3个月出生，那么它第5个月开始会每个月生一只兔子。
//一月的时候有一只兔子，假如兔子都不死，问第n个月的兔子总数为多少？
//数据范围：输入满足 1≤n≤31 1≤n≤31
//输入描述：
//输入一个int型整数表示第n个月
//输出描述：
//输入：1 2 3 4 5 6 9
//输出：1 1 2 3 5 8 34
//https://www.nowcoder.com/practice/1221ec77125d4370833fd3ad5ba72395?tpId=37&&tqId=21260&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

//斐波那契数列 -- 非递归的方法
// int main() 
// {
//     int n = 0;
//     while(~scanf("%d", &n))
//     {
//         int num1 = 1; int num2 = 1; int ret = 1;
//         while(n>2)
//         {
//             ret = num1 + num2;
//             num2 = num1;
//             num1 = ret;
//             n--;
//         }
//         printf("%d\n",ret);
//     }
//     return 0;
// }



//递归的方法
//int Fab(int n)
//{
//    if (n <= 2)
//        return 1;
//    else
//        return Fab(n - 1) + Fab(n - 2);
//}
//int main()
//{
//    int n = 0;
//    while (~scanf("%d", &n))
//    {
//        int ret = Fab(n);
//        printf("%d\n", ret);
//    }
//    return 0;
//}




//b 2
//ZJ16 数列的和
//数列的定义如下：数列的第一项为n，以后各项为前一项的平方根，求数列的前m项的和。
//输入描述：
//输入数据有多组，每组占一行，由两个整数n（n < 10000）和m(m < 1000)组成，n和m的含义如前所述。
//输出描述：
//对于每组输入数据，输出该数列的和，每个测试实例占一行，要求精度保留2位小数。
//示例1
//输入：
//81 4
//2 2
//输出：
//94.73
//3.41
//https://www.nowcoder.com/practice/fe19f8a78a5148018f4be53ae9b5e11e?tpId=182&&tqId=34521&rp=1&ru=/ta/exam-all&qru=/ta/exam-all/question-ranking

#include <math.h>
//int main()
//{
//    double n = 0; int m = 0;
//    while (~scanf("%lf %d", &n, &m))
//    {
//        int i = 0; double sum = 0;
//        for (i = 0; i < m; i++)
//        {
//            sum += n;
//            n = sqrt(n);
//        }
//        printf("%.2lf\n", sum);
//    }
//    return 0;
//}




//day14
//一、选择题
// x1 --> B     指针相减
// 循环在*t为0时停止，同时t++，t最后会停在字符串结束的'\0'之后的一个位置，t作为尾部指针减去头部指针就是整个字符
//串占用内存的字节数，包含\0在内；而c答案字符串长度不包括最后的\0
//1、有以下函数，该函数的功能是（ ）
//int fun(char* s)
//{
//	char* t = s;
//	while (*t++);
//	return(t - s);
//}
//A: 比较两个字符的大小 B : 计算s所指字符串占用内存字节的个数
//C : 计算s所指字符串的长度 D : 将s所指字符串复制到字符串t中


//x 2 --> B 2.5 ***×*** 
//  后置++ 语句运行完后再加一 pa指向a[0] a[0]=1.5*3=4.5， 结束后pa+1 指向a[2]
//2、若有“ float a[3] = { 1.5,2.5,3.5 }, *pa = a; *(pa++) *= 3; ”，则* pa 的值是（ ）
//A : 1.5 B : 2.5 C : 3.5 D : 4.5



//x 3 --> A  ***×***
// 指针q初始化为NULL，接着又解引用指针q，是错误的，对NULL指针是不能解引用的。
//  q = (p + 5);  这样写才是 6  11
//3、以下程序运行后的输出结果是（ ）
//int main()
//{
//	int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, * p = a + 5, * q = NULL;
//	*q = *(p + 5);  
//	printf("%d %d\n", *p, *q);
//	return 0;
//}
//A: 运行后报错 B : 6 6 C : 6 11 D : 5 10




//x 4 --> B
//4、设有定义 char* p[] = { "Shanghai","Beijing","Honkong" }; 则结果为 j 字符的表达式是（ ）
//A : *p[1] + 3 B : *(p[1] + 3) C : *(p[3] + 1) D : p[3][1]





//x 5 --> B
// A--不同类型指针一般不可以直接赋值  C选项中，p=NULL;和p=0;是等价的；
//D选项中，指向同一数组的两指针变量进行关系运算可表示它们所指数组元素之间的位置关系
//5、以下叙述中正确的是（ ）
//A : 即使不进行强制类型转换，在进行指针赋值运算时，指针变量的基类型也可以不同
//B : 如果企图通过一个空指针来访问一个存储单元，将会得到一个出错信息
//C : 设变量p是一个指针变量，则语句p = 0; 是非法的，应该使用p = NULL;
//D: 指针变量之间不能用关系运算符进行比较



//二、编程题
//面试题 16.15.珠玑妙算
//珠玑妙算游戏（the game of master mind）的玩法如下。
//计算机有4个槽，每个槽放一个球，颜色可能是红色（R）、黄色（Y）、绿色（G）或蓝色（B）。
//例如，计算机可能有RGGB 4种（槽1为红色，槽2、3为绿色，槽4为蓝色）。作为用户，你试图猜出颜色组合。
//打个比方，你可能会猜YRGB。要是猜对某个槽的颜色，则算一次“猜中”；
//要是只猜对颜色但槽位猜错了，则算一次“伪猜中”。注意，“猜中”不能算入“伪猜中”。
//给定一种颜色组合solution和一个猜测guess，编写一个方法，返回猜中和伪猜中的次数answer，
//其中answer[0]为猜中的次数，answer[1]为伪猜中的次数。
//示例：
//输入： solution = "RGBY", guess = "GGRR"
//输出：[1, 1]
//解释： 猜中1次，伪猜中1次。
//https://leetcode.cn/problems/master-mind-lcci/

 //这好像传入的是常量字符串 不行！ 数组字符串就可以。  只测了两个也不知道到底对不对
//int* masterMind(char* solution, char* guess, int* returnSize)
//{
//    static char ret[2] = { 0 };
//    int i = 0; int count1 = 0; int count2 = 0;
//    *returnSize = 0;
//    for (i = 0; i < 4; i++)
//    {
//        if (solution[i] == guess[i])
//        {
//            guess[i] = 0;
//            solution[i] = 0;
//            count1++;
//        }
//    }
//    ret[*returnSize] = count1;
//    for (i = 0; i < 4; i++)
//    {
//        int j = 0;
//        for (j = 0; j < 4; j++)
//        {
//            if (solution[i] == 0)
//                break;
//            if (solution[i] == guess[j])
//            {
//                solution[i] = 0;
//                count2++;
//            }
//        }
//    }
//    ret[(*returnSize) + 1] = count2;
//    return ret;
//}
//int main()
//{
//    char arr1[] = "RGBY";
//    char arr2[] = "GGRR";
//    int n = 0;
//    masterMind(arr1, arr2, &n);
//    return 0;
//}



//字母当下标的思想
//int* masterMind(char* solution, char* guess, int* returnSize)
//{
//    // static int ret[2] = { 0 };  //或者用menset
//    // ret[0]=0;ret[1]=0; //静态空间不会进行二次初始化因此每次重新初始化，可以使用memset函数
//    *returnSize = 2;
//    int* ret = (int*)calloc(*returnSize, sizeof(int));
//    int i = 0; int s_arr[26] = { 0 }; int g_arr[26] = { 0 }; //二十六个字母
//    for (i = 0; i < 4; i++)
//    {
//        if (solution[i] == guess[i])
//        {
//            ret[0] += 1;
//        }
//        else
//        {
//            s_arr[solution[i] - 'A'] += 1;//统计solution对应颜色字符出现次数
//            g_arr[guess[i] - 'A'] += 1;//统计guess对应颜色字符出现次数
//        }
//    }
//    for (i = 0; i < 26; i++)
//    {
//        ret[1] += s_arr[i] > g_arr[i] ? g_arr[i] : s_arr[i];
//        // if(s_arr[i]>g_arr[i])
//        //     ret[1] += g_arr[i];
//        // else        //是else哦 因为会包含==情况
//        //     ret[1] += s_arr[i];
//    }
//    return ret;
//}



//b 2
//NC61 两数之和
//给出一个整型数组 numbers 和一个目标值 target，请在数组中找出两个加起来等于目标值的数的下标，返回的下标按升序排列。
//（注：返回的数组下标从1开始算起，保证target一定可以由数组里面2个数字相加得到）
//数据范围：2≤len(numbers)≤1052≤len(numbers)≤105，−10≤numbersi≤109−10≤numbersi​≤109，0≤target≤1090≤target≤109
//要求：空间复杂度 O(n)O(n)，时间复杂度 O(nlogn)O(nlogn)
//输入：[3, 2, 4], 6
//返回值：[2, 3]
//说明：因为 2 + 4 = 6 ，而 2的下标为2 ， 4的下标为3 ，又因为 下标2 < 下标3 ，所以返回[2, 3]
//https://www.nowcoder.com/practice/20ef0972485e41019e39543e8e895b7f?tpId=188&&tqId=38589&rp=1&ru=/activity/oj&qru=/ta/job-code-high-week/question-ranking

 //没有过滤就过不了这个题目，筛掉一部分
#include <memory.h>
#include <stdlib.h>
int* twoSum(int* numbers, int numbersLen, int target, int* returnSize)
{
    *returnSize = 2; int i = 0;
    int* ret = (int*)calloc(*returnSize, sizeof(int));//可加创建失败的代码
    // static int ret[2] = {0};
    // memset(ret, 0x00, sizeof(ret)); //或者 ret[0]=0;ret[1]=0;

    for (i = 0; i < numbersLen; i++)
    {
        //要+10 因为可能为为负数 要过滤掉一部分 负数最大是-10
        //如果一个正数-10了还>目标数，肯定不能再通过相加得到target
        if (numbers[i] - 10 > target)
            continue;
        int j = 0;
        for (j = i + 1; j < numbersLen; j++)
        {
            if (target == numbers[i] + numbers[j])
            {
                ret[0] = i + 1;
                ret[1] = j + 1;
                return ret;
            }
        }
    }
    *returnSize = 0;
    return NULL;
}

